<?php
/***********************************************************************
 * @package    IvanEngine
 * @subpackage Core
 * @author     Ivan <ivanzx@msn.com>
 * @created    2010-05-13
 ***********************************************************************/
if(defined("IVANENGINE_CORE_STL_MAP"))
	die("Redefinition macro in :".__FILE__."(".__LINE__.")");
define("IVANENGINE_CORE_STL_MAP", true);

require_once (dirname(__FILE__).'/Array.php');

class CMapIterator extends CIterator
{
	public function __construct(CArray & $object, $where)
	{
		parent::__construct($object, $where);
		if( !$object instanceof CMap )
		  throw new CException('CMapIterator only for CMap object.');
	}
	
	public function __destruct()
	{
		parent::__destruct();
	}
	
	public function Key()
	{
		return $this->m_object->GetKey($this->m_where);
	}
}

class CMap extends CArray
{
	public function __construct(array $array = null) 
	{
		parent::__construct();
	}

	public function __destruct()
	{
		parent::__destruct();
	}
	
	//---------------------------------------------------------------
	// implements abstract function of base class
    public function Add($key, $val)
    {
    	if(func_num_args() != 2){
            throw new CException('CMap::Add function must pass two parameters: key and value.');
    	}
        if( !array_key_exists($key, $this->m_array) ){
            $this->m_array[$key]   = $val;
        }else{
            return false;
        }
    	return true;
    }
    
    public function RemoveByKey($where)
    {
        if( is_integer($where) ){
            $key    = $this->GetKey($where);
            if( $key ){
                unset($this->m_array[$key]);
            }
        }else{
            unset($this->m_array[$where]);
        }
    }
    
    public function Remove($value)
    {
    	$pos = array_search($value, $this->m_array);
        if( $pos !== FALSE ){
            $this->RemoveByKey($pos);
        }
    }
    
	public function & Get($where)
	{
		if( is_integer($where) ){
			return parent::Get($this->GetKey($where));
		}else{
			return parent::Get($where);
        }
	}
	
	public function Set($where, $val)
	{
		if( is_integer($where) ){
			parent::Set($this->GetKey($where), $val);
		}else{
			parent::Set($where, $val);
		}
	}

	public function Begin()
	{
		return new CMapIterator($this, 0);
	}
	
	public function End()
	{
		return new CMapIterator($this, $this->Size());
	}
	
	public function & Values()
	{
		return array_values($this->m_array);
	}
	
	//---------------------------------------------------------------
	// self function
	
	public function HasKey($key)
	{
		return array_key_exists($key, $this->m_array);
	}
	
	public function GetKey($index)
	{
        $keys = array_keys($this->m_array);
        return $keys[$index];
	}
	
    public function Keys()
    {
        return array_keys($this->m_array);
    }
}

?>